/**
 * SSE 工具类
 * 新增一个 finished 事件，用于通知前端任务已完成
 */
import { getToken } from "@/utils/cache/cookies"

export interface SseConfig {
  url: string // 基础 URL（不含查询参数）
  params?: Record<string, any> // 查询参数
  onMessage: (message: string) => void // 消息处理回调
  onOpen?: () => void // 连接成功回调
  onError?: () => void // 连接错误回调
  onComplete?: () => void // 连接完成回调
}

class SseConnection {
  private eventSource: EventSource | null = null

  // 拼接 URL，追加 token 和参数
  private buildUrl(url: string, params: Record<string, any> = {}): string {
    const token = getToken()
    if (!token) {
      throw new Error("未找到 token，请登录后再试")
    }

    // 添加 token 到参数
    params.token = token

    // 构建查询字符串
    const queryString = Object.entries(params)
      .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
      .join("&")

    return `${import.meta.env.VITE_BASE_API}${url}?${queryString}`
  }

  // 建立 SSE 连接
  connect(config: SseConfig) {
    if (this.eventSource) {
      console.warn("SSE 已经连接，请勿重复连接")
      return
    }

    const finalUrl = this.buildUrl(config.url, config.params)
    this.eventSource = new EventSource(finalUrl)

    // 监听连接打开事件
    this.eventSource.onopen = () => {
      console.log("SSE 连接已建立")
      config.onOpen?.()
    }

    // 监听消息事件
    this.eventSource.onmessage = (event) => {
      console.log("收到消息：", event.type, event.data)
      config.onMessage(event.data)
    }

    // 监听名为 "finished" 的事件 console.log("Received finished event: ", event.data)
    this.eventSource.addEventListener("finished", (event) => {
      console.log("Received finished event(表示任务已完成): ", event.data)
      config.onComplete?.()
      this.disconnect() // 自动断开连接
    })

    // 监听错误事件
    this.eventSource.onerror = () => {
      console.error("SSE 连接发生错误或已断开")
      config.onError?.()
      this.disconnect() // 自动断开连接
    }
  }

  // 断开 SSE 连接
  disconnect() {
    if (this.eventSource) {
      this.eventSource.close()
      this.eventSource = null
      console.log("SSE 连接已断开")
    }
  }
}

export default SseConnection
